<?php

declare(strict_types=1);

namespace So\App\Controller\Backend;

use Hyperf\HttpServer\Annotation\PutMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use So\Controller\Backend;
use So\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use So\Annotation\Auth;
use So\Annotation\AdminLog;
use Hyperf\DbConnection\Db;
use So\Library\Tree;
use So\Library\Auth as AuthLib;
use Hyperf\Di\Annotation\Inject;
use Psr\Http\Message\ResponseInterface;

/**
 * @Controller(prefix="config")
 * @Auth
 * @AdminLog({"config/read","config/menu"})
 */
class ConfigController extends Backend
{
    /**
     * @Inject()
     * @var AuthLib
     */
    protected $auth;

    /**
     * @GetMapping("read")
     */
    public function read($model): ResponseInterface
    {
        $group = config('config_group') ?: json_decode(Db::table('config')->where('name', '=', 'config_group')->value('value'), true);
        foreach ($group as &$v) {
            $config = Db::table('config')->where('group', $v['key'])->orderBy('id', 'asc')->get();
            $config_array = [];
            foreach ($config as $b) {
                $config_array[] = array_merge($b, ['value' => config($b['name']), 'content' => $b['content'] ? (json_decode($b['content'], true) ?: $b['content']) : '']);
            }
            $v['config'] = $config_array;
        }
        return $this->success('ok', array_values($group));
    }

    /**
     * @PostMapping("create")
     */
    public function create($data, $model): ResponseInterface
    {
        $data = [
            'name' => $this->request->filter('name/s'),
            'group' => $this->request->filter('group/s'),
            'title' => $this->request->filter('title/s'),
            'tip' => $this->request->filter('tip/s'),
            'type' => $this->request->filter('type/s'),
            'value' => $this->request->filter('value/s'),
            'content' => $this->request->filter('content/s'),
        ];
        foreach ($data as $k => $v) {
            if (in_array($k, ['name', 'title', 'type']) && !$v) $this->error('请填写完整');
            if (!$v) unset($data[$k]);
        }
        $res = Db::table("config")->where("name", '=', $data['name'])->first();
        if ($res) {
            return $this->error('配置已存在，不可重复添加');
        }
        $id = Db::table("config")->insertGetId($data);
        if (!$id) {
            return $this->error('添加失败');
        }
        return $this->success('添加成功');
    }

    /**
     * @PutMapping("update")
     */
    public function update($data, $model): ResponseInterface
    {
        $data = $this->request->all();
        if (!$data) $this->error();
        $config = [];
        foreach ($data as $k => $v) {
            $res = Db::table('config')->where('name', $k)->first();
            if ($res) {
                $config[$k] = $v;
                if (is_array($v)) $v = json_encode($v, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
                Db::table('config')->where('name', $k)->update(['value' => $v]);
            }
        }
        $config_center_class = config("so.config_center.drive");
        $config_center_method = config("so.config_center.method");
        try {
            $drive = make($config_center_class);
            $pull = $drive->$config_center_method($config);
        } catch (\Exception $e) {
            $this->error('配置发布更新出错');
        }
        if ($pull['code'] !== 200) {
            $this->error($pull['message'] ?? '发布失败');
        }
        return $this->success('同步更新配置成功');
    }

    /**
     * @GetMapping("menu")
     */
    public function menu(): ResponseInterface
    {
        $rules = $this->auth->getRuleList($this->auth->jwt(), false, false);
        foreach ($rules as &$rule) {
            if ($rule['type'] == 'button') unset($rules[$k]);
        }
        $list = Tree::instance()->init($rules, 'pid', ' ')->getTreeList(Tree::instance()->getTreeArray(0), 'title');
        $array = [];
        foreach ($list as $v) {
            $array[] = ['id' => $v['id'], 'title' => $v['title']];
        }
        return $this->success(count($list), $array);
    }
}